package com.changgou.search.service.impl;

import com.changgou.search.service.SearchService;

import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class SearchServiceImpl implements SearchService {

  //es的模板:做es的操作
  @Autowired
  private ElasticsearchTemplate elasticsearchTemplate;

  @Override
  public Map searchMap(Map<String, String> searchMap) {
    //1.构建查询
    if (searchMap != null) {
      //构建查询条件封装对象
      NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
      //条件的构建:组合条件对象
      BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
      //1. 关键词,按照name关键词查询,Operator.AND条件的拼接
      if (StringUtils.isNotEmpty(searchMap.get("keywords"))) {
        boolQuery.must(QueryBuilders.matchQuery("name", //name匹配查询:也可叫做模糊查询
            searchMap.get("keywords")).operator(Operator.AND));  //封装条件
      }
      //2:条件 按照品牌过滤查询
      if (StringUtils.isNotEmpty(searchMap.get("brand"))) {
        boolQuery.filter(QueryBuilders.termQuery("brandName",
            searchMap.get("brand")));
      }

      //4  品牌聚合(分组)查询   //需要封装聚合分组查询结果
      String skuBrand = "skuBrand";
      nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms(skuBrand).field("brandName"));

      //5. 规格聚合(分组)查询 //需要封装聚合分组查询结果
      String skuSpec = "skuSpec";
  nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms(skuSpec).field("spec.keyword"));

      //6:条件 价格区间查询
      if (StringUtils.isNotEmpty(searchMap.get("price"))) {
        String[] p = searchMap.get("price").split("‐");
        if (p.length == 2){
          boolQuery.filter(QueryBuilders.rangeQuery("price").lte(p[1]));  //小于
        }
        boolQuery.filter(QueryBuilders.rangeQuery("price").gte(p[0]));//大于
      }
      //7: 分页
      String pageNum = searchMap.get("pageNum"); //获取当前页
      if (pageNum == null) {
        pageNum = "1"; //如果为null,给定第一页
      }
      String pageSize = searchMap.get("pageSize");//每页显示条数
      if (pageSize == null) {
        pageSize = "30"; //如果为null,给定每页显示30条
      }
      //设置分页
      nativeSearchQueryBuilder.withPageable(PageRequest.of(Integer.parseInt(pageNum)-1, Page.pageSize));

      //8: 排序 评价排序
      /**
       * sortField对这个域进行排序
       * sortRule 按照哪种方式进行排序:ASC和 DESC
       */
      if (!StringUtils.isEmpty(searchMap.get("sortField")&&!StringUtils.isEmpty(searchMap.get("sortRule")
          )) {//按照sortField这个域进行排序
        if ("ASC".equals(searchMap.get("sortRule"))) { //升序
          nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(searchMap.get("sortField")).order(SortOrder.ASC));
        } else {
          //降序
          nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(searchMap.get("sortField")).order(SortOrder.DESC));
        }
      }

//      9.高亮,name高亮显示<span style='color:red'> ,样式为red红色
      HighlightBuilder.Field field = new  HighlightBuilder().Field("name").preTags("<span style='color:red'>").postTags("</span>");
      nativeSearchQueryBuilder.withHighlightFields(field);

      //添加条件
      nativeSearchQueryBuilder.withQuery(boolQuery);


      //6 开启查询
      /**
       * 参数1:条件构建对象
       * 参数2:查询操作实体类
       * 参数3:查询结果操作对象
       */
      elasticsearchTemplate.queryForPage(nativeSearchQueryBuilder.build(), SkuInfo.class, new SearchResultMapper() {
        @Override
        public <
        T > AggregatedPage < T > mapResults(SearchResponse searchResponse, Class < T > aClass, Pageable pageable) {
          //查询结果操作
          List<T> list = new ArrayList<>();
          SearchHits hits = searchResponse.getHits(); //当前查询的结果集合
          if (hits != null) {
            for (SearchHit hit : hits) { //hit索引库中每一条document,对应的一条商品信息
              //hit转换成skuInfo
              SkuInfo skuInfo = JSON.parseObject(hit.getSourceAsString(), SkuInfo.class);
              list.add((T) skuInfo);
            }
          }
          /**
           * 参数1数据集合
           * 参数2分页对象
           * 参数3获取总记录数
           * 参数4: searchResponse.getAggregations()
           */
          return new AggregatedPageImpl<T>(list, pageable,
              hits.getTotalHits(), searchResponse.getAggregations());
        }
      }
    );

//      封装最终的返回结果
      //11. 总条数
      resultMap.put("total", aggregatedPage.getTotalElements());
      //12. 总页数
      resultMap.put("totalPages", aggregatedPage.getTotalPages());
      //13. 查询结果集合
      resultMap.put("rows", aggregatedPage.getContent());

      //14. 分装品牌的聚合分组结果
      StringTerms brandTerms = (StringTerms) aggregatedPage.getAggregation(skuBrand);
      List<String> brandList = brandTerms.getBuckets().stream().map(bucket ‐ >
          bucket.getKeyAsString()).collect(Collectors.toList());
      resultMap.put("brandList", brandList);
      //15. 封装规格聚合分组结果
      StringTerms specTerms = (StringTerms) aggregatedPage.getAggregation(skuSpec);
      List<String> specList = specTerms.getBuckets().stream().map(bucket ‐ >
          bucket.getKeyAsString()).collect(Collectors.toList());
      resultMap.put("specList", specList(specList));

      //16. 返回当前页
     resultMap.put("pageNum", pageNum);

      return resultMap;
    }

    //2.封装查询结果
    return null;
  }
}
